#include "lib/memory/pvmmemory.h"

#include "lib/pvmdriver.h"
#include "lib/pvmstrings.h"
#include "lib/pvmsystem.h"

#if defined(SHP)
	#define PVM_DRIVERS_COUNT	2
	#define PVM_DRIVERS_DEFAULTSLOT	0
	extern IPVMDriverDesc* PVMGetDriverDescBada();
	extern IPVMDriverDesc* PVMGetDriverDescRawWriter();
#elif ((defined(_WIN32_WCE) || defined(WIN32)) && !defined(__SYMBIAN32__))

#if defined(PVM_USE_OAL_DIRECT)
	#define PVM_DRIVERS_COUNT	2
	#define PVM_DRIVERS_DEFAULTSLOT	0
	extern IPVMDriverDesc* PVMGetDriverDescOALDirect();
	extern IPVMDriverDesc* PVMGetDriverDescRawWriter();
#else
	#define PVM_DRIVERS_COUNT	2
	#define PVM_DRIVERS_DEFAULTSLOT	0
	extern IPVMDriverDesc* PVMGetDriverDescWinMM();
	extern IPVMDriverDesc* PVMGetDriverDescRawWriter();
#endif

#elif defined(__SYMBIAN32__)
	#define PVM_DRIVERS_COUNT	2
	#define PVM_DRIVERS_DEFAULTSLOT	0
	extern IPVMDriverDesc* PVMGetDriverDescSymbianAOS();
	extern IPVMDriverDesc* PVMGetDriverDescRawWriter();

#elif defined (IPHONE)
	#define PVM_DRIVERS_COUNT	2
	#define PVM_DRIVERS_DEFAULTSLOT	0
	extern IPVMDriverDesc* PVMGetDriverDescOALDirect();
	extern IPVMDriverDesc* PVMGetDriverDescRawWriter();
#elif defined (__ANDROID__)
	#define PVM_DRIVERS_COUNT	2
	#define PVM_DRIVERS_DEFAULTSLOT	0
	extern IPVMDriverDesc* PVMGetDriverDescAndroidAudioTrack();
	extern IPVMDriverDesc* PVMGetDriverDescRawWriter();
#elif defined (__linux) && !defined(TIZEN)
	#define PVM_DRIVERS_COUNT	2
	#define PVM_DRIVERS_DEFAULTSLOT	0
	extern IPVMDriverDesc* PVMGetDriverDescPulse();
	extern IPVMDriverDesc* PVMGetDriverDescRawWriter();
#elif defined(IW_PLATFORM_S3E)
	#define PVM_DRIVERS_COUNT	2
	#define PVM_DRIVERS_DEFAULTSLOT	0
	extern IPVMDriverDesc* PVMGetDriverDescs3eSound();
	extern IPVMDriverDesc* PVMGetDriverDescRawWriter();
#elif defined(TIZEN)
	#define PVM_DRIVERS_COUNT	2
	#define PVM_DRIVERS_DEFAULTSLOT	0
	extern IPVMDriverDesc* PVMGetDriverDescTizen();
	extern IPVMDriverDesc* PVMGetDriverDescRawWriter();
#endif



static IPVMDriverBase* drivers[PVM_DRIVERS_COUNT];
static IPVMDriverDesc* driversDesc[PVM_DRIVERS_COUNT];

void PVMDriversInit()
{
	for(int i=0; i<PVM_DRIVERS_COUNT; i++)
	{
		drivers[i] = NULL;
	}

#if (defined(WIN32)||defined(_WIN32_WCE)) && !defined(PVM_USE_OAL_DIRECT) && !defined(SHP)
	driversDesc[0] = PVMGetDriverDescWinMM();
	driversDesc[1] = PVMGetDriverDescRawWriter();
#endif

#if (defined(WIN32)||defined(_WIN32_WCE)) && defined(PVM_USE_OAL_DIRECT) && !defined(SHP)
	driversDesc[0] = PVMGetDriverDescOALDirect();
	driversDesc[1] = PVMGetDriverDescRawWriter();
#endif

#if defined(IPHONE)
	driversDesc[0] = PVMGetDriverDescOALDirect();
	driversDesc[1] = PVMGetDriverDescRawWriter();
#endif
	
#if defined(__SYMBIAN32__)
	driversDesc[0] = PVMGetDriverDescSymbianAOS();
	driversDesc[1] = PVMGetDriverDescRawWriter();
#endif

#if defined(SHP)
	driversDesc[0] = PVMGetDriverDescBada();
	driversDesc[1] = PVMGetDriverDescRawWriter();
#endif

#if defined(__ANDROID__)
	driversDesc[0] = PVMGetDriverDescAndroidAudioTrack();
	driversDesc[1] = PVMGetDriverDescRawWriter();
#endif

#if defined(MEEGO_EDITION_HARMATTAN)
	driversDesc[0] = PVMGetDriverDescPulse();
	driversDesc[1] = PVMGetDriverDescRawWriter();
#endif

#if defined(IW_PLATFORM_S3E)
	driversDesc[0] = PVMGetDriverDescs3eSound();
	driversDesc[1] = PVMGetDriverDescRawWriter();
#endif	

#if defined(TIZEN)
	driversDesc[0] = PVMGetDriverDescTizen();
	driversDesc[1] = PVMGetDriverDescRawWriter();
#endif	
}

pvm_int32 PVMDriversCount()
{
	return PVM_DRIVERS_COUNT;
}

pvm_int32 PVMCopyDriverName(const pvm_char* srcBuf, pvm_char* dstBuffer, pvm_uint32 dstMaxLength)
{
	pvm_uint32 srcStrLength = pvm_strlen(srcBuf);
	if(dstBuffer==0||dstMaxLength<=0)
		return srcStrLength;
	
	if(dstMaxLength<srcStrLength+1)
		return 0;

	pvm_strcpy(dstBuffer, srcBuf);
	return srcStrLength;
}

pvm_int32 PVMDriverNameShort(pvm_int32 driverNum, pvm_char* buffer, pvm_uint32 maxLength)
{
	if(driverNum==-1)
		driverNum = PVM_DRIVERS_DEFAULTSLOT;

	if(driverNum<0||driverNum>=PVM_DRIVERS_COUNT)
		return -1;

	return driversDesc[driverNum]->DriverNameShort(buffer, maxLength);
}

pvm_int32 PVMDriverNameFull(pvm_int32 driverNum, pvm_char* buffer, pvm_uint32 maxLength)
{
	if(driverNum==-1)
		driverNum = PVM_DRIVERS_DEFAULTSLOT;

	if(driverNum<0||driverNum>=PVM_DRIVERS_COUNT)
		return -1;

	return driversDesc[driverNum]->DriverNameFull(buffer, maxLength);
}

pvm_uint32 PVMDriverTypeAndFlags(pvm_int32 driverNum)
{
	if(driverNum==-1)
		driverNum = PVM_DRIVERS_DEFAULTSLOT;

	if(driverNum<0||driverNum>=PVM_DRIVERS_COUNT)
		return 0;

	return driversDesc[driverNum]->DriverTypeAndFlags();
}

pvm_bool PVMDriverLoad(pvm_int32 driverNum)
{

	IPVMDriverBase* driver = NULL;
	if(driverNum==-1)
		driverNum = PVM_DRIVERS_DEFAULTSLOT;

	if(driverNum<0||driverNum>=PVM_DRIVERS_COUNT)
		return false;

	if(drivers[driverNum]!=NULL)
		return true;

	driver = driversDesc[driverNum]->DriverLoad();

	if(driver==NULL)
		return false;

	if(!driver->Init())
	{
		driver->DriverClose();
		return false;
	}

	drivers[driverNum] = driver;

	return true;
}

void PVMDriverUnload(pvm_int32 driverNum)
{
	if(driverNum<-1||driverNum>=PVM_DRIVERS_COUNT)
		return;

	if(driverNum==-1)
		driverNum = PVM_DRIVERS_DEFAULTSLOT;

	if(drivers[driverNum]==NULL)
		return;

	drivers[driverNum]->DriverClose();
	drivers[driverNum] = NULL;
}

void PVMDriverUnloadAll()
{
	for(int i=0; i<PVM_DRIVERS_COUNT; i++)
		PVMDriverUnload(i);
}

IPVMDriverBase* PVMDriverGet(pvm_int32 driverNum)
{
	if(driverNum<-1||driverNum>=PVM_DRIVERS_COUNT)
		return NULL;

	if(driverNum==-1)
		driverNum = PVM_DRIVERS_DEFAULTSLOT;

	return drivers[driverNum];
}
